package com.quectel.cms.controller.camera;

import com.quectel.business.common.device.DeviceExtraAttrCls;
import com.quectel.business.dms.AccessorUtils;
import com.quectel.business.dms.application.access.accessor.im.AbstractIntelligentMonitorAccessor;
import com.quectel.business.dms.application.access.accessor.im.model.PlaybackPart;
import com.quectel.business.dms.application.access.accessor.im.model.SearchMapReq;
import com.quectel.business.dms.application.access.accessor.im.model.SearchMapResp;
import com.quectel.business.dms.device.DeviceIntegrationBusiness;
import com.quectel.cms.controller.BaseController;
import com.quectel.cms.vo.device.monitor.DevicePlaybackPartReqVo;
import com.quectel.cms.vo.device.monitor.SearchMapReqVo;
import com.quectel.cms.vo.device.monitor.SearchMapRespVo;
import com.quectel.constant.global.annotation.RequirePermissions;
import com.quectel.core.module.application.dto.ApplicationDto;
import com.quectel.core.module.application.service.ApplicationService;
import com.quectel.core.module.device.dto.DeviceDto;
import com.quectel.core.module.device.dto.DeviceTypeDto;
import com.quectel.core.module.device.service.DeviceCategoryService;
import com.quectel.core.module.device.service.DeviceService;
import com.quectel.core.module.device.service.DeviceTypeService;
import com.quectel.util.common.CopyUtils;
import com.quectel.util.common.DateUtils;
import com.quectel.util.common.Page;
import com.quectel.util.common.Response;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.math.RoundingMode;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author rananxin
 * @date 2021/11/22 2:18 下午
 */
@RestController
@RequestMapping("monitorDevice")
@Tag(name = "MonitorDeviceController", description = "监控设备管理相关api")
public class MonitorDeviceController extends BaseController {

    @DubboReference
    private DeviceService deviceService;
    @DubboReference
    private DeviceCategoryService deviceCategoryService;
    @DubboReference
    private ApplicationService applicationService;
    @DubboReference
    private DeviceTypeService deviceTypeService;
    @Autowired
    private DeviceIntegrationBusiness deviceIntegrationBusiness;

    @GetMapping("searchMap")
    @RequirePermissions(values = "device:info")
    @Operation(summary = "以图搜图")
    public Response<Page<SearchMapRespVo>> searchMap(SearchMapReqVo searchMapReqVo) {
        ApplicationDto applicationDto = applicationService.selectById(searchMapReqVo.getApplicationId());
        if (applicationDto == null) {
            return Response.error("app is null");
        }

        DeviceTypeDto deviceTypeDto = deviceTypeService.selectById(applicationDto.getDeviceTypeId());
        AbstractIntelligentMonitorAccessor intelligentMonitorAccessor = AccessorUtils.getIntelligentMonitorAccessor(deviceTypeDto);
        if (intelligentMonitorAccessor == null) {
            return Response.error("app not connected");
        }

        SearchMapReq searchMapReq = CopyUtils.copyObj(searchMapReqVo, SearchMapReq.class);
        searchMapReq.setApplicationDto(applicationDto);
        if (StringUtils.isNotBlank(searchMapReqVo.getStartTime()) && StringUtils.isNotBlank(searchMapReqVo.getEndTime())) {
            searchMapReq.setStartTime(DateUtils.parse(searchMapReqVo.getStartTime(), DateUtils.FormatType.COMMON));
            searchMapReq.setEndTime(DateUtils.parse(searchMapReqVo.getEndTime(), DateUtils.FormatType.COMMON));
        }

        SearchMapResp searchMapResp = intelligentMonitorAccessor.searchMap(searchMapReq);

        List<SearchMapRespVo> resultList = searchMapResp.getSearchMapList().stream().map(o -> {
            SearchMapRespVo searchMapRespVo = CopyUtils.copyObj(o, SearchMapRespVo.class);
            searchMapRespVo.setSimilarity(o.getSimilarity().setScale(2, RoundingMode.HALF_UP).floatValue());
            return searchMapRespVo;
        }).collect(Collectors.toList());

        Page<SearchMapRespVo> page = new Page<>(searchMapReqVo.getPageNo()
                , searchMapReqVo.getPageSize(), searchMapResp.getTotal()
                , resultList);

        return Response.<Page<SearchMapRespVo>>ok().wrap(page);
    }

    @GetMapping("getPlaybackPart")
    @RequirePermissions(values = "device:info")
    @Operation(summary = "获取回放片段")
    public Response<List<PlaybackPart>> getPlaybackPart(DevicePlaybackPartReqVo devicePlaybackPartReqVo) {

        DeviceDto deviceDto = deviceService.selectById(devicePlaybackPartReqVo.getDeviceId());
        if (Objects.isNull(deviceDto)) {
            return Response.error("未找到设备");
        }

        List<PlaybackPart> list = deviceIntegrationBusiness.getPlaybackPart(deviceDto
                , DateUtils.parse(devicePlaybackPartReqVo.getStartTime(), DateUtils.FormatType.COMMON)
                , DateUtils.parse(devicePlaybackPartReqVo.getEndTime(), DateUtils.FormatType.COMMON));

        return Response.<List<PlaybackPart>>ok().wrap(list);
    }

    @GetMapping("getStreamUrl")
    @RequirePermissions(values = "device:info")
    @Operation(summary = "通过设备id,获取直播流")
    public Response<String> getStreamUrl(Long id) {
        DeviceDto deviceDto = deviceService.selectById(id);
        if (Objects.isNull(deviceDto)) {
            return Response.error("未找到设备");
        }

        deviceIntegrationBusiness.fillDevicesStreamUrl(Arrays.asList(deviceDto));

        DeviceExtraAttrCls.AttrOfIntelligentMonitor attr = DeviceExtraAttrCls.parseExtStr(DeviceExtraAttrCls.AttrOfIntelligentMonitor.class
                , deviceDto.getExtraAttr());

        if (StringUtils.isBlank(attr.getStreamUrl())) {
            return Response.error("the stream does not exist");
        }
        return Response.<String>ok().wrap(attr.getStreamUrl());
    }
}
